package com.mapfinal.api.service;

import java.util.List;

import org.locationtech.jts.geom.Geometry;

import com.jfinal.plugin.activerecord.Record;
import com.lambkit.common.util.StringUtils;
import com.mapfinal.MapFinal;
import com.mapfinal.data.LayerManager;
import com.mapfinal.data.MapLayer;
import com.mapfinal.data.MapStore;
import com.mapfinal.data.StoreManager;

public class GeoApiServiceImpl implements GeoApiService {

	class GeoApiAction {
		public GeoApiService service;
		public MapStore store;
		public MapLayer layer;
		
		public GeoApiAction(GeoApiService service, MapStore store, MapLayer layer) {
			this.service = service;
			this.store = store;
			this.layer = layer;
		}
	}
	public GeoApiAction getDataSourceGeoApiService(String layerName) {
		if(StringUtils.isBlank(layerName)) return null;
		MapStore store = null;
		MapLayer layer = null;
		System.out.println("GeoApiAction layer: " + layerName);
		if(layerName.indexOf(":") > 0) {
			String[] lns = layerName.split(":");
			String storeName = lns[0];
			String lname = lns[1];
			store = StoreManager.me().getStore(storeName);
			System.out.println("GeoApiAction store : " + storeName);
			if(store!=null) {
				layer = store.getLayer(lname);
			}
		} else {
			layer = LayerManager.me().getLayer(layerName);
			if(layer!=null) {
				store = StoreManager.me().getStore(layer.getStoreName());
			}
		}
		if(layer!=null && store!=null) {
			System.out.println("GeoApiAction type : " + store.getType());
			GeoApiService service = MapFinal.me().getGeoApiServiceFactory().create(store.getType());
			return new GeoApiAction(service, store, layer);
		}
		return null;
	}
	
	@Override
	public List<Record> distance(String layerName, Geometry geometry) {
		// TODO Auto-generated method stub
		GeoApiAction action = getDataSourceGeoApiService(layerName);
		if(action!=null) {
			return action.service.distance(action.layer.getNativeName(), geometry);
		}
		return null;
	}

	@Override
	public List<Record> dwithin(String layerName, Geometry geometry, float dist) {
		// TODO Auto-generated method stub
		GeoApiAction action = getDataSourceGeoApiService(layerName);
		if(action!=null) {
			System.out.println("action for layer: " + action.layer.getNativeName());
			return action.service.dwithin(action.layer.getNativeName(), geometry, dist);
		}
		return null;
	}

	@Override
	public List<Record> equals(String layerName, Geometry geometry) {
		// TODO Auto-generated method stub
		GeoApiAction action = getDataSourceGeoApiService(layerName);
		if(action!=null) {
			return action.service.equals(action.layer.getNativeName(), geometry);
		}
		return null;
	}

	@Override
	public List<Record> disjoin(String layerName, Geometry geometry) {
		// TODO Auto-generated method stub
		GeoApiAction action = getDataSourceGeoApiService(layerName);
		if(action!=null) {
			return action.service.disjoin(action.layer.getNativeName(), geometry);
		}
		return null;
	}

	@Override
	public List<Record> intersects(String layerName, Geometry geometry) {
		// TODO Auto-generated method stub
		GeoApiAction action = getDataSourceGeoApiService(layerName);
		if(action!=null) {
			return action.service.intersects(action.layer.getNativeName(), geometry);
		}
		return null;
	}

	@Override
	public List<Record> touches(String layerName, Geometry geometry) {
		// TODO Auto-generated method stub
		GeoApiAction action = getDataSourceGeoApiService(layerName);
		if(action!=null) {
			return action.service.touches(action.layer.getNativeName(), geometry);
		}
		return null;
	}

	@Override
	public List<Record> crosses(String layerName, Geometry geometry) {
		// TODO Auto-generated method stub
		GeoApiAction action = getDataSourceGeoApiService(layerName);
		if(action!=null) {
			return action.service.crosses(action.layer.getNativeName(), geometry);
		}
		return null;
	}

	@Override
	public List<Record> within(String layerName, Geometry geometry) {
		// TODO Auto-generated method stub
		GeoApiAction action = getDataSourceGeoApiService(layerName);
		if(action!=null) {
			return action.service.within(action.layer.getNativeName(), geometry);
		}
		return null;
	}

	@Override
	public List<Record> overlaps(String layerName, Geometry geometry) {
		// TODO Auto-generated method stub
		GeoApiAction action = getDataSourceGeoApiService(layerName);
		if(action!=null) {
			return action.service.overlaps(action.layer.getNativeName(), geometry);
		}
		return null;
	}

	@Override
	public List<Record> contains(String layerName, Geometry geometry) {
		// TODO Auto-generated method stub
		GeoApiAction action = getDataSourceGeoApiService(layerName);
		if(action!=null) {
			return action.service.contains(action.layer.getNativeName(), geometry);
		}
		return null;
	}

	@Override
	public List<Record> covers(String layerName, Geometry geometry) {
		// TODO Auto-generated method stub
		GeoApiAction action = getDataSourceGeoApiService(layerName);
		if(action!=null) {
			return action.service.covers(action.layer.getNativeName(), geometry);
		}
		return null;
	}

	@Override
	public List<Record> coveredby(String layerName, Geometry geometry) {
		// TODO Auto-generated method stub
		GeoApiAction action = getDataSourceGeoApiService(layerName);
		if(action!=null) {
			return action.service.coveredby(action.layer.getNativeName(), geometry);
		}
		return null;
	}

}
